/** Archivo: cliente.java
 *  Autores: Grace Gimon 08-10437
 *           Daniel Montenegro 08-10762
 * Define un cliente que se conecta con un servidor y le realiza 
 * serie de consultas asociadas a biblioteca de musica: Permite consultar
 * una cancion por titulo, por autor y descargarla.
 */

import java.net.*;
import java.io.*;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;

public class cliente {
  private Socket socket;
  private BufferedReader clientIn;
  private PrintWriter clientOut;
  private int portC = 10762;
  private int portD = 10437;
  private String IP; 
  private String dirDownload = null;
  private List<Cancion> cancionesEncontradas = new ArrayList<Cancion>();
  private List<String> nodosAlc = new ArrayList<String>();

    public cliente() {
    }

  /* public cliente(String host, int portNumber, String dirDownload)
   * Param: host: IP/hostname del nodo
   *        portNumber: Numero del puerto a conectar
   *        dirDownload: Opcional, es el path del directorio de descarga
   * Return: Objeto cliente con un socket "socket" abierto
   */
public cliente(String host, int portNumber, String dirDownload){
 
 if (dirDownload != null){
  this.dirDownload = dirDownload;    
 
 }
 this.IP = host;
    try {
        InetAddress inet = InetAddress.getByName(host);
        socket = new Socket(inet, portNumber);
        System.out.println("Puerto del cliente: " + socket);
        
        this.clientIn= new BufferedReader(new InputStreamReader(socket.getInputStream())); 
        this.clientOut = new PrintWriter(socket.getOutputStream(), true);
    }
    catch (IOException e) {
        System.out.println("Excepcion de E/S : " + e);
    }
  
}
/* public static String conocidosToString(List<String> conocidos)
 * Param : conocidos : Lista de todos los nodos conocidos
 * Return: String de todos los nodos conocidos concatenados.
 */
public static String conocidosToString(List<String> conocidos){
        String s = "";    
    for(int i= 0; i<conocidos.size(); i++){
         String c = conocidos.get(i);
          s = s + c + " ";
         }
    return s;
    
}
/* public static void main(String[] args)
 * Param: Numero del puerto
 *        Hostname/IP del nodo
 *        Path del directorio de descarga
 * Se encarga de recibir por entrada standard las consultas que
 * realizara al servidor y muestra por salida standard las respuestas dadas
 * a dichas solicitudes
 * 
 */
public static void main(String[] args) {
    int puerto= 10762;      //Predeterminados
    String nodo = "localhost";
    String dirD = "";
     System.out.println(args.length);
 switch(args.length){
    
     case 4:
         puerto = Integer.parseInt(args[1]);
         nodo = args[3];
         System.out.println(nodo);
         break;
     case 6:
         puerto = Integer.parseInt(args[1]);
         nodo = args[3];
         dirD = args[5];
         break;
     default:
         System.out.println("Par�metros inv�lidos.");
         System.exit(0);
 }
 
 try{  
 BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); 
 String text = in.readLine();
 cliente cliente = new cliente(nodo,puerto,dirD);
 text.trim();
 while(!text.equalsIgnoreCase("q")){
  
     if (text.equalsIgnoreCase("a")){
        String saludo = cliente.clientIn.readLine();
        cliente.clientOut.println(text+"\t"+cliente.IP+"\t"+"N");
        String nodosRecibidos = cliente.clientIn.readLine();
        System.out.println("Nodos alcanzables: \n");
        String[] linea = nodosRecibidos.split(" ");
        for(int i=0; i<linea.length; i++){
            cliente.nodosAlc.add(linea[i]);
            System.out.println("\t"+linea[i]);
        }
        
     }
        
     else if (text.startsWith("c") || text.startsWith("C")){
        if (!cliente.cancionesEncontradas.isEmpty()){
             cliente.cancionesEncontradas.clear();
         }
        String saludo = cliente.clientIn.readLine();
        cliente.clientOut.println(text+"\t"+cliente.IP+"\t"+"N");
        String canciones=" ";
        System.out.println("Resultado de las canciones \n");
        while ((canciones = (cliente.clientIn.readLine()).trim()).
                compareTo("corte")!= 0){
          canciones.trim();
          System.out.println(canciones);
          String[] porlinea = canciones.split("\t");
          Cancion c = new Cancion(Integer.parseInt(porlinea[0].trim()),
                  porlinea[2].trim(),porlinea[1].trim(),porlinea[5].trim(),porlinea[3].trim(),
                  porlinea[4].trim());
          cliente.cancionesEncontradas.add(c);  
          }
     }
     else if (text.startsWith("d") || text.startsWith("D")){
         // Conectarse al nodo dado y Descargar
        String linea[] = text.split(" ");
        if (linea.length <= 1 || linea.length>2){
            System.err.print("Comando invalido");
            break;
        }
        Cancion cancion = cliente.buscarCancionPorNumero(Integer.parseInt(linea[1]));
        System.out.println("Cancion por numero 0 :"+cancion.toString());
        if (cancion.getNodoIP().compareTo(cliente.IP)==0){
            //Procedo a descargarme la cancion pues ya estoy conectada a el nodo
             cliente.clientOut.println(linea[0]+"\t"+cancion.toString());
             System.out.println("\tEnviada solicitud de descarga");
            
        }
        else{
            //DEBO CONECTARME CON EL NODO QUE TIENE LA CANCION
        }
        /* **************************** */
        //Procedo a recibir la cancion
        cliente.recibirCancionMP3();

        
     }
     else{
         System.out.println("Consulta invalida. Intente de nuevo");
     }
    System.out.println("Fin loopp  cliente\n");       
    text = in.readLine();
    text.trim();
   }
 cliente.clientOut.println("q");
   System.out.println("Bye");
   if (cliente !=null){
   cliente.socket.close();
   }
   } catch (IOException ex) {
      Logger.getLogger(cliente.class.getName()).log(Level.SEVERE, null, ex);
    }
 }

public Cancion buscarCancionPorNumero(int ID){
      for (int i= 0; i<this.cancionesEncontradas.size(); i++ ){
        if (this.cancionesEncontradas.get(i).getID() == ID){
           return this.cancionesEncontradas.get(i);
        }
    }
      return null;
}

public void recibirCancionMP3(){
        DataOutputStream output;
        BufferedInputStream bis;
        BufferedOutputStream bos;

        byte[] receivedData;
        int in;
        String file;

        try{
            receivedData = new byte[1024];
            bis = new BufferedInputStream(this.socket.getInputStream());
            DataInputStream dis= new DataInputStream(this.socket.getInputStream());

            //recibimos el nombre del fichero
            file = dis.readUTF();
            System.out.println("EL FILE: "+file);
            file = file.substring(file.indexOf('/')+1,file.length());
            if (this.dirDownload == null){
             bos = new BufferedOutputStream(new FileOutputStream(file));
            }
            else
             bos = new BufferedOutputStream(new FileOutputStream(this.dirDownload+"/"+file));
            while ((in = bis.read(receivedData)) != -1){
                bos.write(receivedData,0,in);
            }
            bos.close();
            dis.close();         
            
        }catch (Exception e ) {
            System.err.println(e);
        }
}
}